﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpHomeEngine
{
    public abstract class Controller : IChangeSource
    {
        private String MyName;
        private System.Threading.Thread MyThread;
        protected StateEngine StateEngine;

        public string Name
        {
            get
            {
                return MyName;
            }
        }

        public System.Threading.Thread Thread
        {
            get
            {
                return MyThread;
            }
        }

        public Controller(StateEngine StateEngine, String Name)
        {
            if (StateEngine == null)
            {
                throw new Exception("State Engine Cannot be null");
            }
            this.StateEngine = StateEngine;
            MyName = Name;
                       
        }

        public void Start() //make internal later
        {
            MyThread = new System.Threading.Thread(new System.Threading.ThreadStart(Execute));
            MyThread.Start();
        }

        /// <summary>
        /// Execute any request in a syncronious fashion.
        /// default timeout of 5 seconds.
        /// </summary>
        /// <param name="Request"></param>
        protected void Execute(Request Request)
        {
            StateEngine.QueueRequest(Request);
            Request.Wait(10000);
        }

        /// <summary>
        /// Execute any request in a syncronious fashion.
        /// </summary>
        /// <param name="Request"></param>
        /// <param name="TimeoutMS"></param>
        protected void Execute(Request Request, UInt16 TimeoutMS)
        {
            StateEngine.QueueRequest(Request);
            Request.Wait(TimeoutMS);
        }

        /// <summary>
        /// Set a tags value in a asyncronious fashion.
        /// </summary>
        /// <param name="Tag"></param>
        /// <param name="Value"></param>
        protected void SetAsync(Tag Tag, Object Value)
        {
            Request4TagStateChange Req = new Request4TagStateChange(this, Tag, Value);
            StateEngine.QueueRequest(Req);
        }

        /// <summary>
        /// Get a tags value in a asyncronious fashion.
        /// </summary>
        /// <param name="Tag"></param>
        protected void GetAsync(Tag Tag)
        {
            Request4TagState Req = new Request4TagState(this, Tag);
            StateEngine.QueueRequest(Req);
        }

        /// <summary>
        /// Set a tags value in a syncronious fashion.
        /// </summary>
        /// <param name="Tag"></param>
        /// <param name="Value"></param>
        protected void SetSync(Tag Tag, Object Value)
        {
            Request4TagStateChange Req = new Request4TagStateChange(this, Tag, Value);
            StateEngine.QueueRequest(Req);
            Req.Wait(5000);
        }

        /// <summary>
        /// Get a tags value in a syncronious fashion.
        /// </summary>
        /// <param name="Tag"></param>
        /// <returns></returns>
        protected Object GetSync(Tag Tag)
        {
            Request4TagState Req = new Request4TagState(this, Tag);
            StateEngine.QueueRequest(Req);
            Req.Wait(5000);
            return Req.Value;
        }

        public abstract void Init();
        public abstract void Execute();


    }
}
